package com.block.product.service.union;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.block.common.service.LogFactory;
import com.block.product.model.dto.UniLoginDTO;
import com.block.product.model.param.ProdApiInfoParam;
import com.block.product.model.result.UnionLoginResult;
import com.block.product.service.IUnionLoginService;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Service
public class MengXinHuaUnionLoginService implements IUnionLoginService {

    private static final Logger log = LogFactory.getProductUniLog();

    @Override
    public UnionLoginResult checkUser(UniLoginDTO uniLoginDTO, ProdApiInfoParam apiInfoParam) throws Exception {
        UnionLoginResult loginResult = new UnionLoginResult();
        loginResult.setSuccess(false);

        String checkUrl = apiInfoParam.getCheckUrl();
        String mobileMd5 = SecureUtil.md5(uniLoginDTO.getMobile()).toLowerCase();

        Map<String, Object> bizmMap = new HashMap<>();
        bizmMap.put("mobile_md5", mobileMd5);

        bizmMap.put("ip", uniLoginDTO.getReqIp());


        String data1 = encrypt(JSON.toJSONString(bizmMap), apiInfoParam.getApiKey(), apiInfoParam.getApiPriKey());


        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("data", data1);
        paramMap.put("channel", apiInfoParam.getApiCode());
        paramMap.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));

        String sign = this.getSignContent(paramMap, apiInfoParam.getApiSecret());


        paramMap.put("sign", sign);

        log.info("【萌薪花】撞库开始【queryUrl】{}【paramMap】{}", checkUrl, JSON.toJSONString(paramMap));
        String result = HttpUtil.createPost(checkUrl).header("Content-Type", "application/json").body(JSON.toJSONString(paramMap)).execute().body();
        log.info("【萌薪花】撞库结束【result】{}", result);

        JSONObject resultObject = JSON.parseObject(result);
        Integer code = resultObject.getInteger("code");
        String msg = resultObject.getString("msg");


        loginResult.setCode(String.valueOf(code));
        loginResult.setMessage(msg);
        loginResult.setResultInfo(result);
        loginResult.setParamInfo(JSON.toJSONString(paramMap));

        if (StrUtil.equals(String.valueOf(code), "0")) {
            JSONObject data = resultObject.getJSONObject("data");
            Integer status = data.getInteger("status");
            if (StrUtil.equals(String.valueOf(status), "1")) {
                loginResult.setSuccess(true);
            }
        }
        return loginResult;
    }

    @Override
    public UnionLoginResult loginUser(UniLoginDTO uniLoginDTO, ProdApiInfoParam apiInfoParam,String resultInfo) throws Exception {

        UnionLoginResult loginResult = new UnionLoginResult();
        loginResult.setSuccess(false);

        String checkUrl = apiInfoParam.getLoginUrl();
        String mobile = uniLoginDTO.getMobile();

        Map<String, Object> bizmMap = new HashMap<>();
        bizmMap.put("mobile", mobile);
        bizmMap.put("ip", uniLoginDTO.getReqIp());

        String data1 = encrypt(JSON.toJSONString(bizmMap), apiInfoParam.getApiKey(), apiInfoParam.getApiPriKey());

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("data", data1);
        paramMap.put("channel", apiInfoParam.getApiCode());
        paramMap.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));


        String sign = this.getSignContent(paramMap, apiInfoParam.getApiSecret());


        paramMap.put("sign", sign);

        log.info("【萌薪花】联登开始【queryUrl】{}【paramMap】{}", checkUrl, JSON.toJSONString(paramMap));
        String result = HttpUtil.createPost(checkUrl).header("Content-Type", "application/json").body(JSON.toJSONString(paramMap)).execute().body();
        log.info("【萌薪花】联登结束【result】{}", result);

        JSONObject resultObject = JSON.parseObject(result);
        Integer code = resultObject.getInteger("code");
        String msg = resultObject.getString("msg");


        loginResult.setCode(String.valueOf(code));
        loginResult.setMessage(msg);
        loginResult.setResultInfo(result);
        loginResult.setParamInfo(JSON.toJSONString(paramMap));

        if (StrUtil.equals(String.valueOf(code), "0")) {
            JSONObject data = resultObject.getJSONObject("data");
            Integer status = data.getInteger("status");
            if (StrUtil.equals(String.valueOf(status), "1")) {
                String url = data.getString("url");
                loginResult.setSuccess(true);
                loginResult.setLoginUrl(url);
            }
        }
        return loginResult;
    }

    // 获取签名内容的方法
    private static String getSignContent(Map<String, Object> paramMap, String signKey) {
        // 获取所有的 key 并进行字母升序排序
        List<String> keyList = new ArrayList<>(paramMap.keySet());
        Collections.sort(keyList);

        // 拼接成 key=value 形式的字符串
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : keyList) {
            String value = String.valueOf(paramMap.get(key)); // 使用 String.valueOf 处理 null 值
            stringBuilder.append(value); // 只添加 value，不需要 key=value 格式
        }

        // 将 sign_key 拼接到字符串末尾
        stringBuilder.append(signKey);

        // 生成 MD5 签名
        String sign = cn.hutool.crypto.SecureUtil.md5(stringBuilder.toString());
        return sign;
    }


    public static String encrypt(String data, String aesKey, String aesIv) throws Exception {

        String jsonData = data;
        if (jsonData.length() % 16 != 0) {
            jsonData = String.format("%-" + (jsonData.length() + 16 - jsonData.length() % 16) + "s", jsonData).replace(' ', '\0');

        }
        if (Objects.equals(data, jsonData)) {
            System.out.println(data);
            System.out.println(jsonData);
        }
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey.getBytes(StandardCharsets.UTF_8), "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(aesIv.getBytes(StandardCharsets.UTF_8));
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] encryptedData = cipher.doFinal(jsonData.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedData);
    }


}
